package view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import util.ResMeetTuple;
import util.ResStepTuple;

import model.Point;
import model.Resource;
import model.Space2D;

public class Histogram extends JFrame {
	private static final long serialVersionUID = 771815446359986822L;
	
	private int antNb;
	private	Space2D space;
	private	ArrayList<ResMeetTuple> res1MeetHistory;
	private	ArrayList<ResMeetTuple> res2MeetHistory;
	private	ArrayList<ResMeetTuple> res3MeetHistory;
	
	/**
	 * Launch the application
	 * @param args
	 */
	public static void main(String args[]) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					//Space2D space = new Space2D(30, 30);
					//space.addAnt(new Ant(space, new Point(0, 0)));
					//Histogram frame = new Histogram(space);
					//frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame
	 */
	public Histogram(Space2D space, int antNb, Color traceColor) {
		super();
		
		//setTitle("Resources Histograms");
		setResizable(true);
		setBounds(100, 100, 600, 400);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		//the data part
		System.out.println("Histogram Constructor : initialize space, res1MeetHistory");
		this.space = space;
		this.antNb = antNb;
		if(traceColor == null) traceColor = Color.MAGENTA;
		
		res1MeetHistory = new ArrayList<ResMeetTuple>();
		res2MeetHistory = new ArrayList<ResMeetTuple>();
		res3MeetHistory = new ArrayList<ResMeetTuple>();
		//System.out.println("Res1MeetHistory size before method analys: " + res1MeetHistory.size());
		analyzeResVisitHistry(getVisitedResList());
		//System.out.println("Res1MeetHistory size after method analys: " + res1MeetHistory.size());
		
		final JTabbedPane tabsPanel = new JTabbedPane();
		getContentPane().add(tabsPanel);

		final JHistoPanel tabPanel1 = new JHistoPanel(Resource.Resource_Type_1, res1MeetHistory);
		tabPanel1.setTraceColor(traceColor);
		tabPanel1.setLayout(null);
		tabsPanel.addTab("Resource Type 1", null, tabPanel1, null);

		final JHistoPanel tabPanel2 = new JHistoPanel(Resource.Resource_Type_2, res2MeetHistory);
		tabPanel2.setTraceColor(traceColor);
		tabPanel2.setLayout(null);
		tabsPanel.addTab("Resource Type 2", null, tabPanel2, null);

		final JHistoPanel tabPanel3 = new JHistoPanel(Resource.Resource_Type_3, res3MeetHistory);
		tabPanel3.setTraceColor(traceColor);
		tabPanel3.setLayout(null);
		tabsPanel.addTab("Resource Type 3", null, tabPanel3, null);
		//
		
		tabPanel1.repaint();
		tabPanel2.repaint();
		tabPanel3.repaint();
		tabsPanel.repaint();
	}

	private Vector<ResStepTuple> getVisitedResList() {
		Vector<Point> histMoves = space.getListAnts().get(antNb).getHistMoves();
		Vector<ResStepTuple> result = new Vector<ResStepTuple>();
		ArrayList resList = space.getListRes();

		Point p1 = null;
		Point p2 = null;
		Resource res = null;
		for(int i = 0; i < histMoves.size(); i++) {
			int nbStep = i;
			p1 = histMoves.get(i);
			for(int j = 0; j < resList.size(); j++) {
				res = (Resource)resList.get(j);
				p2 = res.getLocation();
				if(p1.equals(p2)) {
					result.add(new ResStepTuple(res, nbStep));
				}
			}
		}
		
		return result;
	}
	
	private void analyzeResVisitHistry(Vector<ResStepTuple> visitedResList) {

		ResStepTuple couple1 = null;
		ResStepTuple couple2 = null;
		ResMeetTuple couple3 = null;
		
		if(visitedResList.size() > 0) {
			couple1 = visitedResList.get(0);
		}
		for(int i = 1; i < visitedResList.size(); i++) {
			couple2 = visitedResList.get(i);
			if(couple1.getResource().getType().equals(couple1.getResource().getType())) {
				
				int s = couple2.getStepSequence() - couple1.getStepSequence();
				couple3 = new ResMeetTuple(s, couple1.getResource().getLocation(), couple2.getResource().getLocation());
				
				if(couple1.getResource().getType().equals(Resource.Resource_Type_1)) {
					res1MeetHistory.add(couple3);
				} else if(couple1.getResource().getType().equals(Resource.Resource_Type_2)) {
					res2MeetHistory.add(couple3);
				} else if(couple1.getResource().getType().equals(Resource.Resource_Type_3)) {
					res3MeetHistory.add(couple3);
				}
				//System.out.println("Position 1 : " + couple1.getResource().getLocation() + "; Position 2 : " + couple2.getResource().getLocation() + "; Steps : " + s);
			}
			
			couple1 = couple2;
		}
	}
}

class JHistoPanel extends JPanel {
	private static final long serialVersionUID = -5727528674248665693L;

	private String resType;
	private ArrayList<ResMeetTuple> resMeetHistory;
	private Color traceColor;
	
	public JHistoPanel(String resType, ArrayList<ResMeetTuple> resMeetHistory) {
		super();
		this.resType = resType;
		this.resMeetHistory = resMeetHistory;
	}

	public void drawGrid(Graphics g) {
		this.setBackground(Color.WHITE);
		g.setColor(Color.GRAY);
		for(int i = 0; i < getHeight()/10 + 1; i++) {
			g.drawLine(0, i*10, getWidth(), i*10);
		}
		for(int i = 0; i < getWidth()/10 + 1; i++) {
			g.drawLine(i*10, 0, i*10, getHeight());
		}
		g.setColor(Color.BLACK);
		((Graphics2D)g).setStroke(new BasicStroke(3));
		
		int axeHeight = (getHeight()/10 - 3)*10;
		g.drawLine(30, 20, 30, axeHeight);		
		g.drawLine(30, axeHeight, getWidth()-40, axeHeight);
	}
	
	public void drawAntFlag(Graphics g) {
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, 200, 25);
		
		g.setColor(Color.BLACK);
		((Graphics2D)g).setStroke(new BasicStroke(1));
		g.drawRect(0, 0, 200, 25);
		
		((Graphics2D)g).setStroke(new BasicStroke(3));
		((Graphics2D)g).setFont(new Font("Times New Roman", Font.BOLD, 14));
		g.drawString("Ant Trace Color : ", 10, 15);
		((Graphics2D)g).setStroke(new BasicStroke(2));
		g.drawRect(150, 0, 20, 20);
		g.setColor(traceColor);
		g.fillRect(151, 1, 18, 18);
	}
	
	public void drawProfileFillRect(Graphics g) {
		//draw res histogram 
		//width of axe X : 
		int xWidth = getWidth()-40;
		//height of axe Y : 
		int yHeight = (getHeight()/10 - 10)*10;
		//start X : 
		int startX = 40;
		//finish X : 
		//int finishX = getWidth()-60;
		//maxYHeight : yHeight
		
		//rect width and height according to the proportion
		int rectWidth = 40;
		if(rectWidth * resMeetHistory.size() > xWidth) {
			rectWidth = xWidth/resMeetHistory.size() < 10 ? 10 : xWidth/resMeetHistory.size(); 
		}
		//get the max step
		int maxNbStep = 1;
		ResMeetTuple rmt = null;
		for(int i = 0; i < resMeetHistory.size(); i++) {
			rmt = resMeetHistory.get(i);
			if(rmt.getNbStep() > maxNbStep) {
				maxNbStep = rmt.getNbStep();
			}
		}
		
		int unitStepHeight = yHeight / maxNbStep; 
		
		//draw the profile of the rectangle
		for(int i = 0; i < resMeetHistory.size(); i++) {
			int nbStep = resMeetHistory.get(i).getNbStep();
			int y = (getHeight()/10 - 3)*10 - nbStep*unitStepHeight;

			//profile
			g.setColor(Color.BLACK);
			((Graphics2D)g).setStroke(new BasicStroke(3));
			g.drawRect(startX+i*rectWidth, y, rectWidth, nbStep*unitStepHeight);
			
			//fill
			if(resType.equals(Resource.Resource_Type_1)) {
				g.setColor(Color.RED);
			} else if(resType.equals(Resource.Resource_Type_2)) {
				g.setColor(Color.BLUE);
			} else if(resType.equals(Resource.Resource_Type_3)) {
				g.setColor(Color.GREEN);
			}
			g.fillRect(startX+i*rectWidth+2, y+2, rectWidth-3, nbStep*unitStepHeight-3);
			
			//mark steps
			g.setColor(Color.BLACK);
			((Graphics2D)g).setStroke(new BasicStroke(3));
			((Graphics2D)g).setFont(new Font("Times New Roman", Font.BOLD, 16));
			g.drawString(Integer.toString(nbStep), (int)(startX+(i+0.3)*rectWidth+2), y-10);
		}
	}
	
	public void paint(Graphics g) {
		super.paint(g);
		drawGrid(g);
		drawProfileFillRect(g);
		drawAntFlag(g);
	}

	public String getResType() {
		return resType;
	}

	public void setTraceColor(Color traceColor) {
		this.traceColor = traceColor;
	}
}
